package com.lhf.aicloud.config;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.lhf.aicloud.entity.SecurityUserDetails;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * @author lhf02
 * 登录认证过滤器，用于对每个请求进行身份验证。
 * 通过解析JWT令牌，验证其有效性，并基于令牌中的信息进行用户认证。
 */
@Component
public class LoginAuthenticationFilter extends OncePerRequestFilter {

    /**
     * JWT令牌的密钥，用于令牌的签名和验证。
     */
    @Value("${jwt.secret}")
    private String jwtSecret;

    /**
     * 对每个请求进行过滤，执行认证逻辑。
     *
     * @param request     HTTP请求
     * @param response    HTTP响应
     * @param filterChain 过滤器链，用于继续或停止请求的处理
     * @throws ServletException 如果认证过程中出现Servlet相关异常
     * @throws IOException      如果认证过程中出现IO相关异常
     */
    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
        // 1. 从请求头获取 JWT 令牌
        String token = request.getHeader("Authorization");
        // 2. 判断令牌是否为空, 验证JWT令牌的有效性
        if (StringUtils.hasLength(token) && JWTUtil.verify(token, jwtSecret.getBytes())) {
                // 3. 解析JWT令牌，获取其中的用户信息
                JWT jwt = JWTUtil.parseToken(token);
                if (jwt.getPayload("username") != null) {
                    // 从令牌中获取用户ID和用户名
                    Long uid = Long.parseLong(jwt.getPayload("uid").toString());
                    String username = (String) jwt.getPayload("username");
                    // 创建SecurityUserDetails对象，封装用户认证信息
                    SecurityUserDetails userDetails = new SecurityUserDetails(uid, username, "");
                    // 创建UsernamePasswordAuthenticationToken对象，用于进行认证
                    UsernamePasswordAuthenticationToken authentication =
                            new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    // 设置认证细节，将 userDetails 与 request 进行绑定
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    // 将认证信息设置到SecurityContextHolder中，完成认证
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }

        // 执行下一个过滤器
        filterChain.doFilter(request, response);
    }
}
